/**
 * 시간관련 공통모듈
 * 
 * @author KJH
 * @version 1.0, 2012-02-28 
 * @fix([수정자]) [yyyy-mm-dd]: [수정 내용]
 *
*/

/**
 * 함수 리스트
 * 
 * TimeUtil : 생성자
 * getCurrentTime : 현재시간 가져오기(long형)
 * getDateString : 날짜를 특정형식에 맞게 출력
 * getDateTimeKor : 시간을 한글형식으로 출력
 * getStringKorDate : YYYY년 MM월 DD일 형식을 날짜 출력
 * getStringKorTime : HH시 MM분 ss초 형식의 시간 출력
 * getLongTime : 특정날짜를 밀리초로 계산하여 반환
 * getLastDayOfMon : 특정월의 마지막일을 출력
 * addDay : 특정일을 더하는 함수
 * addHour : 특정시간을 더하는 함수
 * addMinute : 특정분을 더하는 함수
 * prevYearDate : 이전년도의 날짜 출력
 * prevMonthDate : 이전달의 날짜 출력
 * nextYearDate : 다음년도의 날짜 출력
 * nextMonthDate : 다음달의 날짜 출력
 * isExpired : 유효기간이 지났는지 판단
 *
*/

package com.ubst.smartad.common;

import java.util.*;
import java.text.*;

public class TimeUtil{

	public static int TimeZone = 0;	//GMT+0900 (KST)

	public TimeUtil() {
	}

	/**
	 * @author KJH
	 * 현재 시간을 가져오는 함수
	 * 
	 * @param 
	 * @return long : 현재시간
	 *  
	 */
	public static long getCurrentTime() {
		try {
			long currentTime = System.currentTimeMillis() + (long)(1000*60*60*TimeZone);
			return currentTime;
		} catch(Exception e) {
			return 0;
		}
	}

	/**
	 * @author KJH
	 * 특정일을 type형식에 맞게 출력
	 * 
	 * @param changeTime : 변경할 날짜
	 * @param type : 변경형식
	 * @return String : 변경된날짜
	 *  
	 */
	public static String getDateString( long changeTime, String type ) {
		try {
			SimpleDateFormat formatter = new SimpleDateFormat (type, java.util.Locale.KOREA);
			Date CTime = new Date(changeTime);
			String dateString = formatter.format(CTime);
			return dateString;
		} catch(Exception e) {
			return "";
		}
	}

	/** 
	 * <pre> 
	 * 문자열 형태의 날짜를 원하는 형태로 변환합니다. 
	 *  
	 * 예시) 
	 * "yyyy.MM.dd G 'at' HH:mm:ss z"       2001.07.04 AD at 12:08:56 PDT 
	 * "EEE, MMM d, ''yy"   Wed, Jul 4, '01 
	 * "h:mm a"     12:08 PM 
	 * "hh 'o''clock' a, zzzz"      12 o'clock PM, Pacific Daylight Time 
	 * "K:mm a, z"  0:08 PM, PDT 
	 * "yyyyy.MMMMM.dd GGG hh:mm aaa"       02001.July.04 AD 12:08 PM 
	 * "EEE, d MMM yyyy HH:mm:ss Z" Wed, 4 Jul 2001 12:08:56 -0700 
	 * "yyMMddHHmmssZ"      010704120856-0700 
	 * "yyyy-MM-dd'T'HH:mm:ss.SSSZ" 2001-07-04T12:08:56.235-0700 
	 * </pre> 
	 *  
	 * @param date 변환할 날짜 
	 * @param fromFormatString 변환될 포맷 
	 * @param toFormatString 변환할 포맷 
	 * @return 변환된 날짜 문자열 
	 */ 
	public static String formattedDate(String date, String fromFormatString, String toFormatString){ 
			SimpleDateFormat fromFormat = new SimpleDateFormat(fromFormatString); 
			SimpleDateFormat toFormat = new SimpleDateFormat(toFormatString); 
			Date fromDate = null; 
			 
			try 
			{ 
					fromDate = fromFormat.parse(date); 
			} 
			catch(ParseException e) 
			{ 
					fromDate = new Date(); 
			} 
			 
			return toFormat.format(fromDate); 
	} 
	 
	/** 
	 * <pre> 
	 * 날짜를 원하는 형태의 문자열로 반환합니다. 
	 * </pre> 
	 *  
	 * @param date 변환할 Date 인스턴스 
	 * @param format 변환할 포맷 
	 * @return 변환된 날짜 문자열 
	 */ 
	public static String formattedDate(Date date, String format) 
	{ 
			SimpleDateFormat toFormat = new SimpleDateFormat(format); 
			return toFormat.format(date); 
	}

	/**
	 * @author KJH
	 * 시간은 한글형식으로 출력
	 * 
	 * @param date : 변환할 날짜
	 * @return String : 한글형식의 날짜
	 *  
 	 */
	public static String getDateTimeKor(String date) {
		String ret = "";
		try {
			if ( date.length() >= 14 ){
				ret = getStringKorDate(date)+getStringKorTime(date);
			}
		} catch(Exception e) {
			ret = "";
		}
		return ret;
	}

	/**
	 * @author KJH
	 * 날짜를 한글화 하는 함수
	 * 
	 * @param date : 변경할 날짜
	 * @return String : 현재날짜(한글형식)
	 *  
	 */
	public static String getStringKorDate( String date ) {
		String ret = "";
		try {
			if ( date.length() >=8 ){
				ret = date.substring(0, 4)+"년 "+Integer.parseInt(date.substring(4,6))+"월 "+Integer.parseInt(date.substring(6,8))+"일";
			}
		} catch(Exception e) {
			ret = "";
		}
		return ret;
	}

	/**
	 * @author KJH
	 * 시간을 한글화 하는 함수
	 * 
	 * @param date : 변경할 날짜
	 * @return String : 현재시간(한글형식)
	 *  
	 */
	public static String getStringKorTime( String date ) {
		String ret = "";
		try {
			if ( date.length() >=14 ){
				ret = date.substring(8, 10)+"시 "+date.substring(10,12)+"분 "+date.substring(12,14)+"초";
			}
		} catch(Exception e) {
			ret = "";
		}
		return ret;
	}

	/**
	 * @author KJH
	 * 특정날짜를 밀리초단위로 환산하여 반환하는 함수
	 * 
	 * @param date : 변환할 시간
	 * @return long : 변환된 초
	 *  
	 */
	public static long getLongTime( String date ) {
		long ret = 0;
		Calendar cal = Calendar.getInstance();
		try {
			if ( date.length() >=14 ){
				cal.set( Integer.parseInt(date.substring(0,4)), 	
				Integer.parseInt(date.substring(4,6))-1, 	
				Integer.parseInt(date.substring(6,8)), 	
				Integer.parseInt(date.substring(8,10)), 	
				Integer.parseInt(date.substring(10,12)), 	
				Integer.parseInt(date.substring(12,14))  );	
				ret = (cal.getTimeInMillis() + (long)(1000*60*60*TimeZone));
			}
		} catch(Exception e) {
			return ret;
		}
		return ret;
	}

	/**
	 * @author KJH
	 * 특정월의 마지막 일 구하는 함수
	 * 
	 * @param date : 마지막일자를 구할 월
	 * @return String : 마지막일자
	 *  
	 */
	public static String getLastDayOfMon( String date ) {
		String ret = null;
		Calendar cal = Calendar.getInstance();
		try {
			if ( date.length() >= 6 ){
				cal.set( Integer.parseInt(date.substring(0,4)), 	
				Integer.parseInt(date.substring(4,6))-1, 	
				1  );	
				int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
				ret = date.substring(0,6)+String.valueOf(lastDay);
			}
		} catch(Exception e) {
			ret = null;
		}
		return ret;
	}

	/**
	 * @author KJH
	 * 특정일을 더하는 함수
	 * 
	 * @param date : 변경할 날짜
	 * @param day : 특정일 수
	 * @return String : 변경된날짜
	 *  
	 */
	public static String addDay(String date, int day) {
		String addTime = date;
		if(addTime.length()==14){
			int i_year = Integer.parseInt(addTime.substring(0,4));
			int i_month = Integer.parseInt(addTime.substring(4,6));
			int i_day = Integer.parseInt(addTime.substring(6,8));
			int i_hour = Integer.parseInt(addTime.substring(8,10));
			int i_minute = Integer.parseInt(addTime.substring(10,12));
			int i_second = Integer.parseInt(addTime.substring(12,14));
			Calendar calendar=Calendar.getInstance();
			calendar.set(i_year, i_month-1, i_day, i_hour, i_minute, i_second);
			/*
			calendar.set(calendar.YEAR, i_year);
			calendar.set(calendar.MONTH, (i_month-1));  //해당월에 -1을 해주어야 한다.(월은 0부터시작하기때문에)
			calendar.set(calendar.DATE, i_day);
			*/
			
			calendar.add(Calendar.DATE,day); //위의 임의의 날짜에서 다음날짜 가져오기(현재날짜 가져올때는 삭제)
			addTime = getDateString( calendar.getTimeInMillis() + (long)(1000*60*60*TimeZone), "yyyyMMddHHmmss" );
		}
		return addTime;
	}

	/**
	 * @author KJH
	 * 특정시간 더하는 함수
	 * 
	 * @param date : 변경할 날짜
	 * @param term : 특정일 수
	 * @return String : 변경된날짜
	 *  
	 */
	public static String addHour(String date, int term) {
		String addTime = date;
		if(addTime.length()==14){
			int i_year = Integer.parseInt(addTime.substring(0,4));
			int i_month = Integer.parseInt(addTime.substring(4,6));
			int i_day = Integer.parseInt(addTime.substring(6,8));
			int i_hour = Integer.parseInt(addTime.substring(8,10));
			int i_minute = Integer.parseInt(addTime.substring(10,12));
			int i_second = Integer.parseInt(addTime.substring(12,14));
			Calendar calendar=Calendar.getInstance();
			calendar.set(i_year, i_month-1, i_day, i_hour, i_minute, i_second);
			/*
			calendar.set(calendar.YEAR, i_year);
			calendar.set(calendar.MONTH, (i_month-1));  //해당월에 -1을 해주어야 한다.(월은 0부터시작하기때문에)
			calendar.set(calendar.DATE, i_day);
			calendar.set(calendar.HOUR, i_hour);
			*/

			calendar.add(Calendar.HOUR, term); 
			addTime = getDateString( calendar.getTimeInMillis() + (long)(1000*60*60*TimeZone), "yyyyMMddHHmmss" );
		}
		return addTime;
	}

	/**
	 * @author KJH
	 * 특정분을 더하는 함수
	 * 
	 * @param date : 변경할 날짜
	 * @param term : 변경할 분
	 * @return String : 변경된날짜
	 *  
	 */
	public static String addMinute(String date, int term) {
		String addTime = date;
		if(addTime.length()==14){
			int i_year = Integer.parseInt(addTime.substring(0,4));
			int i_month = Integer.parseInt(addTime.substring(4,6));
			int i_day = Integer.parseInt(addTime.substring(6,8));
			int i_hour = Integer.parseInt(addTime.substring(8,10));
			int i_minute = Integer.parseInt(addTime.substring(10,12));
			int i_second = Integer.parseInt(addTime.substring(12,14));
			Calendar calendar=Calendar.getInstance();
			calendar.set(i_year, i_month-1, i_day, i_hour, i_minute, i_second);

			calendar.add(Calendar.MINUTE, term); 
			addTime = getDateString( calendar.getTimeInMillis() + (long)(1000*60*60*TimeZone), "yyyyMMddHHmmss" );
		}
		return addTime;
	}

	/**
	 * @author KJH
	 * 이전년도 날짜 구하는 함수 함수
	 * 
	 * @param date : 현재 날짜
	 * @param term : 날짜를 구할 년도
	 *
	 * @return 변경된 년도 및 월
	 *  
	 */
	public static String prevYearDate(String date, int term){
		String prev_date = null;
		try{
			if(date.length()>=8){
				int curYear = Integer.parseInt(date.substring(0,4));
				int curMonth = Integer.parseInt(date.substring(4,6));
				int curDay = Integer.parseInt(date.substring(6,8));
				Calendar prevMonthCal = Calendar.getInstance();
				Calendar tempCal = Calendar.getInstance();
				int tempCurDay = curDay;
				tempCal.set(curYear-term,curMonth-1,1);
				if(curDay > tempCal.getActualMaximum(Calendar.DATE)){
					tempCurDay = tempCal.getActualMaximum(Calendar.DATE);
				}
				prevMonthCal.set(curYear-term,curMonth-1,tempCurDay);
				prev_date = getDateString( prevMonthCal.getTimeInMillis() + (long)(1000*60*60*TimeZone), "yyyyMMddHHmmss" );
			}
		}catch(Exception e){
			prev_date = null;
		}

		return prev_date;
	}

	/**
	 * @author KJH
	 * 이전달 날짜 구하는 함수 함수
	 * 
	 * @param date : 현재 날짜
	 * @param term : 날짜를 구할 이전월
	 *
	 * @return 변경된 년도 및 월
	 *  
	 */
	public static String prevMonthDate(String date, int term){
		String prev_date = null;
		try{
			if(date.length()>=8){
				int curYear = Integer.parseInt(date.substring(0,4));
				int curMonth = Integer.parseInt(date.substring(4,6));
				int curDay = Integer.parseInt(date.substring(6,8));
		        Calendar prevMonthCal = Calendar.getInstance();
				Calendar tempCal = Calendar.getInstance();
				int tempCurDay = curDay;
				tempCal.set(curYear-term,curMonth-1,1);
				if(curDay > tempCal.getActualMaximum(Calendar.DATE)){
					tempCurDay = tempCal.getActualMaximum(Calendar.DATE);
				}
				prevMonthCal.set(curYear,curMonth-(term+1),tempCurDay);
				prev_date = getDateString( prevMonthCal.getTimeInMillis() + (long)(1000*60*60*TimeZone), "yyyyMMddHHmmss" );
			}
		}catch(Exception e){
			prev_date = null;
		}
		return prev_date;
	}

	/**
	 * @author KJH
	 * 다음년도 날짜 구하는 함수 함수
	 * 
	 * @param date : 현재 날짜
	 * @param term : 날짜를 구할 다음년도
	 *
	 * @return 변경된 년도 및 월
	 *  
	 */
	public static String nextYearDate(String date, int term)
	{
		String next_date = null;
		try{
			if(date.length()>=8){
				int curYear = Integer.parseInt(date.substring(0,4));
				int curMonth = Integer.parseInt(date.substring(4,6));
				int curDay = Integer.parseInt(date.substring(6,8));

				Calendar nextMonthCal = Calendar.getInstance();
				Calendar tempCal = Calendar.getInstance();
				int tempCurDay = curDay;
				tempCal.set(curYear+term,curMonth-1,1);
				if(curDay > tempCal.getActualMaximum(Calendar.DATE)){
					tempCurDay = tempCal.getActualMaximum(Calendar.DATE);
				}
				nextMonthCal.set(curYear+term,curMonth-1,tempCurDay);
				next_date = getDateString( nextMonthCal.getTimeInMillis() + (long)(1000*60*60*TimeZone), "yyyyMMddHHmmss" );
			}
		}catch(Exception e){
			next_date = null;
		}
		return next_date;
	}


	/**
	 * @author KJH
	 * 다음달 날짜 구하는 함수 함수
	 * 
	 * @param date : 현재 날짜
	 * @param term : 날짜를 구할 다음 월
	 *
	 * @return 변경된 년도 및 월
	 *  
	 */
	public static String nextMonthDate(String date, int term)
	{
		String next_date = null;
		try{
			if(date.length()>=8){
				int curYear = Integer.parseInt(date.substring(0,4));
				int curMonth = Integer.parseInt(date.substring(4,6));
				int curDay = Integer.parseInt(date.substring(6,8));

				Calendar nextMonthCal = Calendar.getInstance();
				Calendar tempCal = Calendar.getInstance();
				int tempCurDay = curDay;
				tempCal.set(curYear+term,curMonth-1,1);
				if(curDay > tempCal.getActualMaximum(Calendar.DATE)){
					tempCurDay = tempCal.getActualMaximum(Calendar.DATE);
				}
				nextMonthCal.set(curYear,curMonth+(term-1),tempCurDay);
				next_date = getDateString( nextMonthCal.getTimeInMillis() + (long)(1000*60*60*TimeZone), "yyyyMMddHHmmss" );
			}
		}catch(Exception e){
			next_date = null;
		}
		return next_date;
	}

	/**
	 * @author KJH
	 * 유효기간이 지났는지 판단
	 * 
	 * @param date : 판단할 날짜
	 * @param day : 특정일 수
	 *
	 * @return 유효기간유무
	 *  
	 */
	public static boolean isExpired(String date, int day) {
		boolean flag = true;

		String expire_day = addDay(date, day);

		if(getLongTime(expire_day)>=getCurrentTime()){
			flag = false;
		}
		return flag;
	}

}
